! VSemiletov, 08.2011
! Calculation of noise signal in every listener's position from every surfaces

subroutine CalcNoiseSignal()
use Data_cfoam, only: p,rho,U, pnew,rhonew,unew, sound,Pfon, &
                      meshCellOut, &
                      nump,rank, ierr, &
                      Pobs, Pobsw, nValues, nprint
use DataTime, only: ttime,dtout,dt,dt2, nstep
use Acoustics, only: nAcousticSurfaces,AcousticSurface, nListeners,Listener, nNoiseSignals,NoiseSignal
implicit none
    include 'mpif.h'

    real(8) :: dpdt,drdt,dUdt(3)
    integer :: i,j, iNS, nFL, iS,iL
    character(280) :: nameFile

    do iS = 1,nAcousticSurfaces
        if(AcousticSurface(iS)%CalcAcoustics.eqv..false.)then
        
            if(AcousticSurface(iS)%nextTimeOut.gt.ttime)cycle
            call AcousticsOut(AcousticSurface(iS)%AcousticsOut, &
                                  AcousticSurface(iS)%LengthAcousticsOut, &
                                  AcousticSurface(iS)%nCellsOut, &
                                  AcousticSurface(iS)%CellsOut)

            AcousticSurface(iS)%nextTimeOut = AcousticSurface(iS)%nextTimeOut + AcousticSurface(iS)%dTimeOut * &
                              (1d0 + int((ttime-AcousticSurface(iS)%nextTimeOut)/AcousticSurface(iS)%dTimeOut))

            cycle
        end if
    end do

    do iNS = 1,nNoiseSignals
        iS = NoiseSignal(iNS)%iSurface
        iL = NoiseSignal(iNS)%iListener
        
        if(AcousticSurface(iS)%CalcAcoustics.eqv..false.)then
            cycle
        end if
        
        NoiseSignal(iNS)%nValues = 0
	    do j=1,AcousticSurface(iS)%nCellsOut
		    i=meshCellOut(j)
		    dpdt=(pnew(i)-p(i))/dt2
		    drdt=(rhonew(i)-rho(i))/dt2
		    dUdt(1:3)=(Unew(1:3,i)-U(1:3,i))/dt2

		    call def_p_conv(NoiseSignal(iNS)%Pobs, &
		                    Listener(iL)%Location, AcousticSurface(iS)%xOut(1:3,j), &
		                    AcousticSurface(iS)%Area(j), AcousticSurface(iS)%normal(1:3,j), &  ! def_p
				            pnew(i),rhonew(i),unew(1:3,i),sound,Pfon,dpdt,drdt,dudt,ttime, & !dtout
				            AcousticSurface(iS)%dTimeOut,dt,nValues)
!if(nstep.eq.2)then
!            write(999,'(23f15.6,i4,a5,i3)') NoiseSignal(iNS)%Pobs(1:5),AcousticSurface(iS)%Area(j), &     ! 6
!                                      AcousticSurface(iS)%normal(1:3,j), pnew(i),rhonew(i),unew(1:3,i), & !8
!                                      Pfon,dpdt,drdt,dudt,ttime,dtout,dt,nValues, &                     ! 7, 1
!                                      ' rank=',rank
!end if
			NoiseSignal(iNS)%nValues = max(NoiseSignal(iNS)%nValues,nValues)
	    end do

!if(nstep.eq.2)then
!    call MPI_Barrier(MPI_COMM_WORLD,ierr)
!    stop 'her'
!end if

        if (mod(nstep,nprint).eq.0) then
!	    if (mod(nstep, 200).eq.0) then ! 1).eq.0) then !
	    !	if (rank.eq.0) write(*,*) 'FW process started',ttime
	        if (nump.gt.1) then
                call MPI_ALLREDUCE(NoiseSignal(iNS)%nValues,nValues,1,MPI_INTEGER, &
                                   MPI_MAX,MPI_COMM_WORLD,ierr)
	            call MPI_Barrier(MPI_COMM_WORLD,ierr)
	            NoiseSignal(iNS)%nValuesGlobal = nValues
!	            write(*,*) 'nValues=', nValues
!	            write(*,*) 'NoiseSignal(iNS)%nValues=', NoiseSignal(iNS)%nValues
	        else
	            NoiseSignal(iNS)%nValuesGlobal = NoiseSignal(iNS)%nValues
	            nValues = NoiseSignal(iNS)%nValues
	        end if
		    if (rank.eq.0) then
	    !		if (ttime.gt.3e-3) read(*,*)
			    do i=1,nValues*nump !300000*nump
				    Pobsw(i)=0d0
			    end do
		    end if

    !		if (rank.eq.0) write(*,*) 'FW Pobsw zero finished',ttime
    
            do i = 1,nValues !300000
                Pobs(i) = NoiseSignal(iNS)%Pobs(i)
!                write(*,*) '!!!   Pobs(i)=',Pobs(i)
            end do

!		    call MPI_Gather(Pobs,300000, MPI_DOUBLE_PRECISION,Pobsw,300000, MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD,ierr)

	        call MPI_Gather(Pobs,nValues, MPI_DOUBLE_PRECISION,Pobsw,nValues, MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD,ierr)
            call MPI_Barrier(MPI_COMM_WORLD,ierr)

    !		if (rank.eq.0) write(*,*) 'FW net process finished',ttime
		    if (rank.eq.0) then
			    do i=2,nump
				    do j=1,nValues !300000
					    Pobsw(j)=Pobsw(j)+Pobsw(j+(i-1)*nValues) !Pobsw(j)=Pobsw(j)+Pobsw(j+(i-1)*300000)
				    end do
			    end do
			    write(*,*) 'FW process finished',ttime

!if(nstep.eq.2)then
!            write(999,'(5f15.6,a5,i3)') Pobsw(1:5), ' rank=',rank
!end if
!if(nstep.eq.2)then
!!    call MPI_Barrier(MPI_COMM_WORLD,ierr)
!    stop 'her'
!end if
                nFL = NoiseSignal(iNS)%nameFileLength
                nameFile(1:nFL-1) = NoiseSignal(iNS)%outputFile(1:nFL-1)
                
!                write(*,*) 'nFL = ',nFL
                
                if(mod(nstep/nprint,2).eq.0)then
			    !if(mod(nstep/200,2).eq.0)then
			        nameFile(nFL:nFL) = '1'
                else
                    nameFile(nFL:nFL) = '2'
			    end if

!                write(*,*) 'nameFile= ',NoiseSignal(iNS)%outputFile(1:nFL)
!                write(*,*) 'nValues= ',nValues

			    open(21,file=nameFile(1:nFL)) !,access='append')
			    do i=1,nValues ! 300000
				    write(21,*) dtout*(i-1),char(44),Pobsw(i)
			    end do
			    close(21)
		    end if
	    end if
    end do

end subroutine CalcNoiseSignal

subroutine AcousticsOut(name,LengthName,nCellsOut,CellsOut)
use Data_cfoam, only: processor, ie,  pnew,rhonew,Unew
use DataTime, only: ttime,dt, nstep,nStepInitial
implicit none
    character(50),intent(in) :: name
    integer,intent(in) :: LengthName, nCellsOut, CellsOut(nCellsOut)

    integer :: i,j
    integer :: OpenFile

!    if(nstep.eq.nStepInitial)then
!        open(11,file=processor(1:ie)//name(1:LengthName),form='unformatted',IOSTAT=OpenFile)
!    else
!        open(11,file=processor(1:ie)//name(1:LengthName),form='unformatted',position='append',IOSTAT=OpenFile)
!    end if
    open(11,file=name(1:LengthName),form='unformatted',position='append',IOSTAT=OpenFile)
    if (OpenFile.ne.0) then
	    write(*,*) '@@ Fatal Error (AcousticsOut): File open error ', processor(1:ie)//name
	    STOP '@@ Fatal Error!'
    end if

    write(11) ttime,0,nCellsOut
    write(11) (Unew(1:3,CellsOut(i)),pnew(CellsOut(i)),rhonew(CellsOut(i)), i=1,nCellsOut)

    close(11)

end subroutine AcousticsOut
